package com.pet.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pet.dto.*;
import com.pet.entity.HealthRecordDO;
import com.pet.entity.PetDO;
import com.pet.entity.UserDO;
import com.pet.mapper.HealthRecordMapper;
import com.pet.mapper.PetMapper;
import com.pet.service.HealthRecordService;
import com.pet.utils.UserContextUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class HealthRecordServiceImpl extends ServiceImpl<HealthRecordMapper, HealthRecordDO> implements HealthRecordService {

    @Resource
    private HealthRecordMapper healthRecordMapper;
    @Resource
    private PetMapper petMapper;

    @Override
    public Result add(HealthRecordAddDTO dto) {
        if (Objects.isNull(dto.getRecordDate())) {
            return Result.error("记录日期不能为空");
        }
        HealthRecordDO healthRecordDO = new HealthRecordDO();
        BeanUtil.copyProperties(dto, healthRecordDO);
        UserDO currentUser = UserContextUtil.getCurrentUser();
        healthRecordDO.setUserId(currentUser.getId());
        healthRecordMapper.insert(healthRecordDO);
        return Result.success("添加成功");
    }

    @Override
    public List<HealthRecordResDTO> queryList(HealthRecordQueryDTO dto) {
        UserDO currentUser = UserContextUtil.getCurrentUser();
        LambdaQueryWrapper<HealthRecordDO> queryWrapper = Wrappers.<HealthRecordDO>lambdaQuery()
                .eq(HealthRecordDO::getUserId, currentUser.getId())
                .eq(Objects.nonNull(dto.getPetId()), HealthRecordDO::getPetId, dto.getPetId())
                .ge(Objects.nonNull(dto.getStartDate()), HealthRecordDO::getRecordDate, dto.getStartDate())
                .le(Objects.nonNull(dto.getEndDate()), HealthRecordDO::getRecordDate, dto.getEndDate())
                .eq(StringUtils.isNotBlank(dto.getAbnormalEvents()), HealthRecordDO::getAbnormalEvents, dto.getAbnormalEvents())
                .eq(StringUtils.isNotBlank(dto.getAppetiteLevel()), HealthRecordDO::getAppetiteLevel, dto.getAppetiteLevel())
                .eq(Objects.nonNull(dto.getActivityPattern()), HealthRecordDO::getActivityPattern, dto.getActivityPattern())
                .eq(Objects.nonNull(dto.getCoatCondition()), HealthRecordDO::getCoatCondition, dto.getCoatCondition())
                .eq(Objects.nonNull(dto.getEstrusState()), HealthRecordDO::getEstrusState, dto.getEstrusState())
                .eq(Objects.nonNull(dto.getEyeCondition()), HealthRecordDO::getEyeCondition, dto.getEyeCondition())
                .eq(Objects.nonNull(dto.getGroomingFreq()), HealthRecordDO::getGroomingFreq, dto.getGroomingFreq())
                .orderByDesc(HealthRecordDO::getRecordDate);
        List<HealthRecordDO> recordList = healthRecordMapper.selectList(queryWrapper);
        Map<Integer, String> petNameMap;
        if (CollUtil.isNotEmpty(recordList)) {
            Set<Integer> petIds = recordList.stream()
                    .map(HealthRecordDO::getPetId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            LambdaQueryWrapper<PetDO> petQueryWrapper = Wrappers.<PetDO>lambdaQuery()
                    .in(PetDO::getId, petIds);
            List<PetDO> petList = petMapper.selectList(petQueryWrapper);
            petNameMap = petList.stream()
                    .collect(Collectors.toMap(PetDO::getId, PetDO::getName));
        } else {
            petNameMap = Collections.emptyMap();
        }
        return recordList.stream()
                .map(record -> {
                    HealthRecordResDTO healthRecordResDTO = new HealthRecordResDTO();
                    BeanUtil.copyProperties(record, healthRecordResDTO);
                    healthRecordResDTO.setPetName(petNameMap.get(record.getPetId()));
                    return healthRecordResDTO;
                })
                .collect(Collectors.toList());
    }

    @Override
    public Result updateRecord(HealthRecordUpdateDTO dto) {
        LambdaUpdateWrapper<HealthRecordDO> updateWrapper = Wrappers.<HealthRecordDO>lambdaUpdate()
                .eq(HealthRecordDO::getId, dto.getId())
                .set(HealthRecordDO::getCoatCondition, dto.getCoatCondition())
                .set(HealthRecordDO::getActivityPattern, dto.getActivityPattern())
                .set(HealthRecordDO::getAppetiteLevel, dto.getAppetiteLevel())
                .set(HealthRecordDO::getWaterIntake, dto.getWaterIntake())
                .set(HealthRecordDO::getSleepDuration, dto.getSleepDuration())
                .set(HealthRecordDO::getGroomingFreq, dto.getGroomingFreq())
                .set(HealthRecordDO::getEyeCondition, dto.getEyeCondition())
                .set(HealthRecordDO::getStoolQuality, dto.getStoolQuality())
                .set(HealthRecordDO::getUrineOutput, dto.getUrineOutput())
                .set(HealthRecordDO::getBodyTemp, dto.getBodyTemp())
                .set(HealthRecordDO::getMoodState, dto.getMoodState())
                .set(HealthRecordDO::getSocialInteraction, dto.getSocialInteraction())
                .set(HealthRecordDO::getEstrusState, dto.getEstrusState())
                .set(HealthRecordDO::getEstrusDuration, dto.getEstrusDuration())
                .set(HealthRecordDO::getEstrusIntensity, dto.getEstrusIntensity())
                .set(HealthRecordDO::getEstrusSymptoms, dto.getEstrusSymptoms())
                .set(HealthRecordDO::getAbnormalEvents, dto.getAbnormalEvents())
                .set(HealthRecordDO::getNotes, dto.getNotes());
        this.update(updateWrapper);
        return Result.success();
    }

    @Override
    public Result deleteRecord(HealthRecordUpdateDTO dto) {
        LambdaUpdateWrapper<HealthRecordDO> updateWrapper = Wrappers.<HealthRecordDO>lambdaUpdate()
                .eq(HealthRecordDO::getId, dto.getId());
        this.remove(updateWrapper);
        return Result.success();
    }
}